import { Injectable } from '@nestjs/common'
import { Prisma } from '@prisma/client'
import { PrismaService } from 'nestjs-prisma'
import { DomainModel } from '../model'
import { Page, PageDto } from '@libs/lhy-core'
import { FlowTemplateBatchUpsertOnUniqueDto } from './dto/flow-template-batch-upsert-on-unique.dto'

@Injectable()
export class FlowTemplateDao {
  get table() {
    return this.prismaService.flowTemplate
  }

  constructor(private readonly prismaService: PrismaService) {}

  /**
   * 数据分页
   * @param data
   * @returns
   */
  async page(data: PageDto & { label?: string }): Promise<Page<DomainModel.FlowTemplate>> {
    const page = new Page<DomainModel.FlowTemplate>(data)
    delete data.current
    delete data.size

    const result = await this.prismaService.$transaction([
      this.table.findMany({
        skip: page.skip,
        take: page.take,
        where: data,
        orderBy: [
          {
            sortNo: 'desc',
          },
          {
            createTime: 'desc',
          },
        ],
      }),
      this.table.count({ where: data }),
    ])

    page.records = result[0] || []
    page.totals = result[1] || 0

    return page
  }

  /**
   * 数据列表
   * @param data
   * @returns
   */
  list(data: Prisma.FlowTemplateWhereInput): Promise<DomainModel.FlowTemplate[]> {
    return this.table.findMany({
      where: data,
      orderBy: [
        {
          sortNo: 'desc',
        },
        {
          createTime: 'desc',
        },
      ],
    })
  }

  /**
   * 分组列表
   * @param data
   * @returns
   */
  listGroup(data: { platform: string; project?: string }): Promise<string[]> {
    return this.table
      .findMany({
        distinct: ['groupLabel'],
        select: {
          groupLabel: true,
        },
        where: data,
      })
      .then(data => data.map(item => item.groupLabel))
  }

  /**
   * 标签是否存在，平台-项目-分组下的标签名称唯一
   * @param data
   * @returns
   */
  isLabelExists(
    data: Array<{
      label: string
      groupLabel: string
      platform: string
      id?: number
    }>
  ): Promise<boolean> {
    return this.prismaService
      .$transaction(
        data.map(row =>
          this.table.count({
            where: {
              platform: row.platform,
              groupLabel: row.groupLabel,
              label: row.label,
              id: {
                not: row.id,
              },
            },
          })
        )
      )
      .then(result => result.some(count => count > 0))
  }

  /**
   * 保存数据
   * @param data
   * @returns
   */
  save(data: Prisma.FlowTemplateCreateInput): Promise<DomainModel.FlowTemplate> {
    return this.table.create({ data })
  }

  /**
   * 批量保存数据
   * @param data
   */
  batchSave(data: Prisma.FlowTemplateCreateManyInput[]) {
    return this.table.createMany({ data })
  }

  /**
   * 批量新增/更新数据
   * @param data
   */
  async batchUpsertOnUnique(data: FlowTemplateBatchUpsertOnUniqueDto[], belong: DomainModel.FlowTemplateBelong) {
    if (data.length) {
      await this.prismaService.$transaction(
        data.map(row => {
          const { platform, groupLabel, label, ...otherData } = row

          return this.table.upsert({
            create: {
              ...row,
              belong,
            },
            update: otherData,
            where: {
              platform_groupLabel_label: {
                platform,
                groupLabel,
                label,
              },
            },
          })
        })
      )
    }
  }

  /**
   * 根据ID获取数据
   * @param id
   * @returns
   */
  getById(id: number): Promise<DomainModel.FlowTemplate | null> {
    return this.table.findUnique({ where: { id } })
  }

  /**
   * 根据ID更新数据
   * @param id
   * @param data
   * @returns
   */
  updateById(id: number, data: Prisma.FlowTemplateUpdateInput): Promise<DomainModel.FlowTemplate> {
    return this.table.update({ data, where: { id } })
  }

  /**
   * 根据ID删除数据
   * @param id
   * @returns
   */
  deleteById(id: number): Promise<DomainModel.FlowTemplate> {
    return this.table.delete({ where: { id } })
  }
}
